Repository navigation
guest: delete the process modules and cgroups (SL6.11b) - #1542
Pedro Henrique Penna (ppenna) merged 2 commits into
Conversation
This pull request changes existing testsIt modifies or removes 268 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests. Test code
... and 218 more, which the job's summary lists. Relocated unchanged: 0; added: 0. Compared the merge base |
There was a problem hiding this comment.
🟢 Approval recommended
There are no active review issues for the removal of obsolete guest process and cgroup infrastructure.
No open issues 🎉
What changed in this PR
This PR advances NVX’s library-slimming workstream by removing obsolete guest process and cgroup infrastructure after its callers were deleted. It preserves nvx-init’s plain-process execution path and the retained root-switching mechanisms.
Changes:
- Deletes the old guest execution, spawn, process, entry, cgroup, and bootstrap APIs and their unused OS support.
- Retires obsolete tests and adapts retained tests to use the private OS helpers directly.
- Updates documentation, the Linux public API snapshot, and test inventories to reflect the removals.
| File | Description |
|---|---|
scripts/test-layout-allowlist.json |
Removes obsolete test hooks and tightens spawn allowances. |
nvx-rs/src/lib.rs |
Removes deleted modules from the crate documentation. |
nvx-rs/src/guest/view.rs |
Removes the deleted entry import and documentation reference. |
nvx-rs/src/guest/time/api.rs |
Updates spawn-safety documentation without the removed API. |
nvx-rs/src/guest/sys/tests.rs |
Adjusts test-helper exports after deletions. |
nvx-rs/src/guest/sys/spawn/tests.rs |
Retires tests and cases for removed child stages. |
nvx-rs/src/guest/sys/signal/tests.rs |
Uses the retained wait helper for child status checks. |
nvx-rs/src/guest/sys/process/tests.rs |
Removes obsolete process helpers and lookup assertions. |
nvx-rs/src/guest/sys/process.rs |
Deletes unused named-wait and process-group lookup helpers. |
nvx-rs/src/guest/sys/port/tests.rs |
Tests spawn refusal through the private child builder. |
nvx-rs/src/guest/sys/mod.rs |
Removes obsolete exports and updates OS-layer documentation. |
nvx-rs/src/guest/sys/fd/tests.rs |
Deletes the unused descriptor-limit helper. |
nvx-rs/src/guest/sys/fd.rs |
Removes unused per-execution descriptor and socket helpers. |
nvx-rs/src/guest/sys/entry/tests.rs |
Removes entry simulation and deleted structure-size checks. |
nvx-rs/src/guest/spawn.rs |
Deletes the old public spawning API. |
nvx-rs/src/guest/root/tests.rs |
Retires bootstrap tests and fixtures. |
nvx-rs/src/guest/root/kernel/tests.rs |
Removes simulated cgroup writes and process moves. |
nvx-rs/src/guest/root/kernel.rs |
Removes bootstrap-only control-file writes. |
nvx-rs/src/guest/root/bootstrap/tests.rs |
Deletes bootstrap parsing tests. |
nvx-rs/src/guest/root/bootstrap.rs |
Deletes cgroup bootstrap and resource configuration. |
nvx-rs/src/guest/root.rs |
Removes bootstrap APIs, errors, and an unused bind helper. |
nvx-rs/src/guest/process/tests.rs |
Deletes tests for the removed child-status API. |
nvx-rs/src/guest/process.rs |
Deletes the public child-status collector. |
nvx-rs/src/guest/mod.rs |
Removes obsolete module declarations and descriptions. |
nvx-rs/src/guest/mappings.rs |
Removes an unused internal bind re-export. |
nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs |
Routes test signals through the test-helper export. |
nvx-rs/src/guest/init/tests/exec.rs |
Replaces deleted wait and group-lookup helpers. |
nvx-rs/src/guest/cgroup.rs |
Deletes execution cgroup management. |
nvx-rs/src/guest/activation.rs |
Removes a rustdoc reference to the deleted entry check. |
nvx-rs/src/guest/account.rs |
Makes formerly re-exported account items crate-private. |
nvx-rs/README.md |
Removes obsolete module sections and bootstrap descriptions. |
nvx-rs/public-api/linux.txt |
Records removal of guest process and bootstrap APIs. |
doc/guest-agent-guidelines.md |
Removes the transitional description of old process modules. |
doc/acceptance-case-matrix.md |
Records retired examples and updates retained example locations. |
Review effort: Balanced
321bd2b to
bf2c816
Compare
004d770 to
e0eba06
Compare
e0eba06 to
308b255
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
The deletion spans guest fork/exec, credential boundaries, and the guest kernel, warranting maintainer confirmation of workload launch, boot, and restore validation while exact-head CI remains unrun.
No open issues 🎉
Review effort: Balanced
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep their text: SL6.11b (#1542) rewrites them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The old layered init, the managed agent's sandbox mode and the one-shot
container helpers are gone, and with them the last users of the guest
process modules: guest::exec ran a layered root's executions, which
guest::spawn started, guest::entry entered into their namespaces, view
and identity, guest::cgroup placed and guest::process collected, and
guest::root's bootstrap moved the init's processes into the cgroups
that held them. nvx-init runs its workloads as plain processes through
sys::spawn, without per-execution containment.
Delete guest::{exec, spawn, process, cgroup, entry}, with their
submodules and tests, and guest::root::{bootstrap, Bootstrap,
BootstrapStep, Resources}, with root::Error::Bootstrap. Delete the OS
support that only they used:
- sys::entry's per-execution entry: EntryChild, its clone3 start in new
mount, PID and UTS namespaces, its view of /proc, /sys and /dev, with
the procfs entries that it masked or made read-only, its move into
the root, its umask, its working directory's resolution beneath the
root, and the CloneArgs and OpenHow structures. sys::entry keeps a
layered root's runtime file systems and the workload identity, which
nvx-init and Root use.
- The spawn child's per-execution stages, with their ChildSpec setters:
the root, the working directory's credentials check, inherited
descriptors, the cgroup placement, the session, the barrier and the
entry. The child keeps the path of nvx-init's workloads. LaunchStage,
whose numbers the child's launch report carries and which
guest::spawn held, moves into sys::spawn as a crate-private enum of
the stages that the child still takes, each with its number.
- The waits and signals that only guest::exec used: process_group_of,
WaitTarget and wait_named, and the sys re-exports of
signal_process_group and signal_through_pidfd, which sys::process
keeps for kill_process_group and kill_through_pidfd.
- The cgroup writes: root::kernel's Kernel::write, which only the
bootstrap called.
- fd's shut_down_sending, take_pipe_end, open_at and
create_socket_pair, which only guest::exec's pipes and sockets used.
fd's per-execution memfd and seals already left with #1310.
Root::switch keeps its move of the root and its change of root, and
the rooted open keeps its EAGAIN retry. What the warning-denied builds
then find unused goes too: root::bind_runtime_file, whose retained
variant bind_runtime_file_retained takes its rustdoc, and
guest::mappings' bind_with re-export. guest::account's items, which
only guest::entry re-exported, become crate-private.
Tests:
- The deleted modules' 125 tests retire: 44 of guest::exec, among them
a_stalled_sink_stalls_only_its_own_execution_and_loses_nothing, 22
of guest::entry, 22 of guest::spawn, 17 of guest::cgroup, 9 of
guest::process and 2 of guest::root::bootstrap; guest::root's 6
bootstrap tests; and sys::spawn's
a_child_enters_its_root_or_reports_why_not,
the_check_s_credentials_keep_the_parent_s_supplementary_groups and
an_entry_leads_a_session_and_keeps_its_barrier_from_the_program,
whose stages go. So do the deleted modules' 8 doc tests, and the
test hooks of their code and of the deleted child stages.
- sys::spawn's invalid_specs_are_refused_before_forking,
stream_sources_below_the_standard_streams_are_raised_and_kept_from_the_program
and the_launch_descriptors_are_close_on_exec lose their cases of the
credentials check, inherited descriptors and cgroup placement.
- sys::entry's the_kernel_structures_have_their_uapi_sizes loses
CloneArgs and OpenHow, and its Simulation helper goes.
- Tests that used a deleted helper use the kept one:
a_thread_that_may_hold_the_permission_spawns_no_command spawns
through sys::spawn;
a_write_takes_back_its_own_sigpipe_beside_one_pending_for_the_process
and
a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_ending
wait with sys::wait;
privileged_capture_sweep_kills_setsid_escapees_and_spares_both_helpers
reads process groups with getpgid; and the managed agent's runtime
tests signal through sys::tests' signal_through_pidfd.
a_real_time_signal_goes_through_a_pidfd_and_to_a_process_group drops
its check of process_group_of.
- test_nvx_tools.py's
test_readme_gives_each_module_a_short_row_and_a_section expects more
than 30 rows in the nvx README's module table rather than 40, since
the table keeps 39 of its 44; the floor only shows that the test
reads the module table.
- The helpers that only deleted tests used go: root::kernel's fake
writes and process moves, root's bootstrap fixtures,
sys::process's untraced and traced children, sys::fd's
set_descriptor_limit and sys::spawn's CAP_SYS_CHROOT.
Docs: the rustdoc of guest, guest::root, sys and the kept OS modules,
the crate's guest summary, the nvx README, whose module table and
sections drop the five modules, and the guest-agent guidelines no
longer describe the deleted modules or the root's bootstrap. The case
matrix retires the deleted doc tests and names the kept ones by the
lines to which they move. The test-layout allowlist and the Linux
public API snapshot drop the deleted modules.
Part of #1123 (SL6.11b).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
#1123's follow-up K1. With the old layered init, the one-shot container helpers, guest::entry and the runtime adapter gone, the kernel feature inventory named consumers and validators that no longer exist, and kept CONFIG_MAGIC_SYSRQ for the per-execution entry, which made /proc/sysrq-trigger read-only for user ID 0 and is gone too. Nothing that stays uses magic SysRq: no NVX code reads or writes /proc/sysrq-trigger or kernel.sysrq, and nvx-init and the managed agent refuse user ID 0 and drop every capability, so their workloads could not write the trigger anyway. It had a side effect, though: the hvc console took ^O on the kernel console, where an nvx-rs run shell reads, as a SysRq prefix, so ^O never reached bash, vim or nano there, and ^O c, b or o crashed, rebooted or powered off the guest. The diagnostics feature drops it, and kernel/config-microvm and its derived record, regenerated with nvx.py kernel-config in the Docker build's image, lose CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE and CONFIG_MAGIC_SYSRQ_SERIAL with it: the configuration sets 767 symbols, 174 of them inventory settings and 593 derived. The features name what uses them now: - processors and memory-hotplug: nvx-init's restore repair, in nvx::guest::snapshot::capture, which replaced the clone repair, and the snapshot helper. The restore-processors, platform-restore-processors and restore-memory scenarios validate them in place of the adapter's clone tests. - virtio-console, block-storage, sandbox-filesystems and host-filesystem: nvx-init, nvx::guest::root and nvx::guest::activation, in place of nvx-init-agent and nvx::guest::clone. The sandbox-gpt-layer and snapshot-tiers scenarios validate GPT layers in place of the adapter's GPT tests. - sandbox-isolation keeps its settings, which no NVX component uses since SL7.8b, SL7.8c and SL6.11b: its rationale says that only root programs in a guest, such as an nvx-rs run shell, can use them, and that NAMESPACES also stays for NET_NS. build-kernel's sandbox group validates it. Whether they stay is #1123's follow-up K2. - linux-abi and diagnostics no longer name the runtime adapter; CI's logs are diagnostics' only consumer, and build-kernel's configuration checks validate it. doc/build.md lists magic SysRq among what the inventory removed, drops serial SysRq, which no longer appears, from the platform options, and updates the configuration's counts, the cgroup row and the Sandbox group's purpose, which described the old sandbox. Part of #1123 (SL6.11b, follow-up K1). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
308b255 to
9830b1e
Compare
c1198c7
into
feature/nvx-refactor
The README still introduced the crate as the NVX mechanics and their
supervision, laid out the split platform, store and supervisor modules,
listed exec among the modules without default features, kept an
uncompiled copy of lib.rs's example, and gave modules that leave the
public API, or leave the crate, rows and long sections of their own.
It now opens with the library's mechanisms and what it leaves to its
users, links the library guide and the guest-agent guidelines, and
names NVX's programs, with NVXC and the code that only they use, as
private users of the library, whose binaries call hidden mains. Its
features come first, and its layout and module table describe the
final public modules: guest::{exec, spawn, process, cgroup, entry} are
gone; guest::{root, view, gpt}, the mapper and the application of an
activation are nvx-init's space, private to the crate, which a short
section under the guest binaries describes and the guidelines detail;
host::platform is private and host::report a module of its own; and
nvx::protocol::maps and nvx::Error gain rows. The table keeps one line
of at most 200 characters for each of its 36 modules, above the floor
of 30 that #1542 set. The module sections keep each module's contracts
and leave the rest to its rustdoc. NVXC is private and speaks version 2
alone, as SL4.4c and SL4.4d make it; library callers tell errors apart
by their kinds alone; and the Example gives way to the guide, whose
links reach compiled code.
The CLI's sections, the table of error codes, the binaries' table and
the tests stay as they were but for one stale sentence on an API
change: other documents link them, SL6.10d owns the CLI reference, and
the slices that change them keep them current. The table of error codes
keeps guest-features-missing, which a unit test of the base reads, until
SL4.4d removes it.
Docs only: 0 core lines, no counted files.
Part of #1130 (SL6.10a).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep the text that SL6.11b (#1542) gave them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep the text that SL6.11b (#1542) gave them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Leaving code only. This PR changes only code that this effort removes from NVX: the guest process modules (
guest::{exec, spawn, process, cgroup, entry}), the layered root's bootstrap, and the per-execution OS support that only they used, with the edits that remove references to them. Nothing that stays changes, and no later PR uses what it changes, so the size limits for kept code don't apply.The second commit is #1123's follow-up K1, which the group issue gives this PR once
guest::sys::entry's per-execution parts leave: it dropsCONFIG_MAGIC_SYSRQfrom the guest kernel and names the kernel features' current consumers and validators. It changes kept code, within the limits for kept code (43 core lines in 1 counted file).Part of #1123 (SL6.11b, "The process modules and cgroups are gone"). Parent #1087, umbrella #1076.
What and why
SL7.8b (#1534) and SL7.8c (#1536) deleted the old layered init, the managed agent's sandbox mode and the one-shot container helpers, the last users of the guest process modules:
guest::execran a layered root's executions, whichguest::spawnstarted,guest::entryentered into their namespaces, view and identity,guest::cgroupplaced andguest::processcollected, andguest::root's bootstrap moved the init's processes into the cgroups that held them. nvx-init runs its workloads as plain processes throughsys::spawn, without per-execution containment, so nothing calls them any more. Two commits:b4e4937cdoes SL6.11b's Scope, and9830b1e1does follow-up K1.The process modules and cgroups (
b4e4937c)guest::{exec, spawn, process, cgroup, entry}, with their submodules and tests, andguest::root::{bootstrap, Bootstrap, BootstrapStep, Resources}, withroot::Error::Bootstrap.sys::entry:EntryChild, itsclone3start in new mount, PID and UTS namespaces, its view of/proc,/sysand/devwith the procfs entries that it masked or made read-only, its move into the root, its umask and its working directory's resolution beneath the root, and theCloneArgsandOpenHowstructures.sys::entrykeeps a layered root's runtime file systems and the workload identity, which nvx-init andRootuse.ChildSpecsetters: the root, the working directory's credentials check, inherited descriptors, the cgroup placement, the session, the barrier and the entry. The child keeps the path of nvx-init's workloads, unchanged.LaunchStage, whose numbers the child's launch report carries and whichguest::spawnheld, moves intosys::spawnas a crate-private enum of the 10 stages that the child still takes, each with its number (1, 4, 13 to 16, 18 to 21), which nvx-init's launch report and the managed agent decode;from_code, which onlyguest::spawnused, goes.process_group_of,WaitTargetandwait_named, and thesysre-exports ofsignal_process_groupandsignal_through_pidfd, whichsys::processkeeps forkill_process_groupandkill_through_pidfd.guest::cgroup, androot::kernel'sKernel::write, which only the bootstrap's cgroup and sysctl writes called.fd's per-execution support:shut_down_sending,take_pipe_end,open_atandcreate_socket_pair, which onlyguest::exec's pipes and sockets used. Its per-execution memfd and seals already left with guest: run direct workloads on the init exec core #1310.root::bind_runtime_file, whose retained variantbind_runtime_file_retainedtakes its rustdoc, andguest::mappings'bind_withre-export.guest::account's items, which onlyguest::entryre-exported, become crate-private.nvx-rs/public-api/linux.txtdrops the five modules (299 lines), withguest::entry's account re-exports, and the hiddenguest::root::{bootstrap, Bootstrap, BootstrapStep, Resources}androot::Error::Bootstrap;windows.txtdoesn't change, as the guest is Linux-only.guest,guest::root,sysand the kept OS modules, the crate's guest summary inlib.rs,nvx-rs/README.md, whose module table and sections drop the five modules and whose root row and section drop the bootstrap, anddoc/guest-agent-guidelines.mdno longer describe them.scripts/test-layout-allowlist.jsonis tightened (check_test_layout.py --tighten): the deleted modules' test hooks go, andsys/spawn.rs's count falls from 7 to 5.guest::cgroupline 36,guest::entry90,guest::exec79 andExecution::adopt619,guest::process12 and 39,guest::spawn41,LaunchStage::from_code201), and the kept doc tests ofguest/mod.rs,guest/root.rsandlib.rsmove to lines 34, 126 and 53, with the summary's counts.What stays:
Root::switch, with its move of the root and its change of root (Kernel::enter_root, throughsys::spawn::enter_root), the rooted open'sEAGAINretry (sys::rooted), nvx-init's spawn child, the workload identity and runtime file systems ofsys::entry, and every OS helper with a kept caller.Follow-up K1: the kernel's magic SysRq and the features' consumers (
9830b1e1)The decision is on #1123 (#1123 (comment)).
diagnosticsfeature keptCONFIG_MAGIC_SYSRQfor the per-execution entry, which made/proc/sysrq-triggerread-only for user ID 0 and leaves in the first commit, and its only validator was the deleted adapter'svm_layeredtest. Nothing that stays reads or writes/proc/sysrq-triggerorkernel.sysrq, and nvx-init and the managed agent refuse user ID 0 and drop every capability, so their workloads couldn't write the trigger anyway. It had a live side effect: the hvc console took^Oon the kernel console, where annvx-rs runshell reads, as a SysRq prefix, so^Onever reached bash, vim or nano there, and^O c,borocrashed, rebooted or powered off the guest.nvx.py kernel-configin the Docker build's image:kernel/config-microvmhas# CONFIG_MAGIC_SYSRQ is not setin place ofCONFIG_MAGIC_SYSRQ=y,CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1and# CONFIG_MAGIC_SYSRQ_SERIAL is not set, andkernel/config-microvm.deriveddropsCONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE. The configuration sets 767 symbols, 174 by the inventory's 25 features and 593 derived, 52 of them with a prompt (from 769, 175, 594 and 53).vmlinuxshrinks from 21,594,072 to 21,581,680 bytes.processorsandmemory-hotplugnamenvx::guest::snapshot::capture, whose restore repair replaced the clone repair, and the snapshot helper, and are validated by therestore-processors,platform-restore-processorsandrestore-memoryscenarios rather than the adapter's clone tests;virtio-console,block-storage,sandbox-filesystemsandhost-filesystemnamenvx-init,nvx::guest::rootandnvx::guest::activationrather thannvx-init-agentandnvx::guest::clone, andblock-storageis validated by thesandbox-gpt-layerandsnapshot-tiersscenarios rather than the adapter's GPT tests;linux-abianddiagnosticsno longer name the adapter, anddiagnostics' only consumer is CI's logs, validated bybuild-kernel's configuration checks.sandbox-isolationkeeps its settings (decision 2, follow-up K2): its rationale now says that no NVX component uses them since SL7.8b, SL7.8c and SL6.11b, that only root programs in a guest, such as annvx-rs runshell, can use them, and thatNAMESPACESalso stays forNET_NS. It no longer namesnvx-init-agent,nvx-container-launch,nvx::guest::cgroup,nvx::guest::entryornvx-snapshot, whose freezer path nothing reaches;build-kernel's sandbox group validates it.nvx-container-enterwas never named in the file.doc/build.mdlists magic SysRq among what the inventory removed, drops "serial sysrq", which no longer appears, from the platform options, updates the configuration's counts, and rewrites the cgroup row and the Sandbox group's purpose, which described the old sandbox, to match decision 2.CONFIG_MAGIC_SYSRQor thediagnosticsfeature;test_kernel_config.py's checks of the checked-in configuration and the inventory pass with the regenerated files.ubuntu-26.04for the first time.Deliberately left
guest/common/nvx-snapshot's cgroup freezer andnsenter -upaths, which nothing reaches any more, andguest/common/nvx-sandbox-smoke's checks of the old entry, which only its unit tests reach: recorded as follow-ups on nvx-rs slimming 4.2.4: the exec engine, the process modules and the old layered init are gone #1123.doc/build.md's Alpine paragraph about the sandbox PID-1 bootstrap and its container scripts, which SL6.10e rewrites.sandbox-isolation's settings: follow-up K2.doc/modules, whose diagrams still draw the deleted modules: CI redraws and commits them (doc/ci.md).Size
Measured as #1076 defines them, against
feature/nvx-refactor,22163771:b4e4937c)9830b1e1)guest/sys/spawn.rs, of which 29 areLaunchStageand itscode, moved fromguest::spawnwith the stages that stay, and the rest its imports and the child's conditions without the deleted stages; 7 inguest/sys/mod.rs, the re-export lists without the deleted items, as rustfmt wraps them; and 1 each inguest/sys/entry.rsandguest/sys/fd.rs(imports) andguest/mappings.rs(the re-export withoutbind_with).guest/account.rs's 6 lines only make items crate-private, so they don't count.guest/mod.rs,guest/mappings.rs,guest/root.rs,guest/root/kernel.rs,guest/view.rsandguest/sys/{entry,fd,mod,process,spawn}.rs, innvx-rs/src/. Not counted:guest/account.rs(crate-private only),lib.rs,guest/activation.rsandguest/time/api.rs(rustdoc only), the 12 deleted files, tests, docs, the allowlist and the generated API snapshot. - K1 (43 core lines, 1 counted file):scripts/nvx_tools/kernel_features.py, whose rationales, consumers and validations change, and whosediagnosticsfeature dropsCONFIG_MAGIC_SYSRQ=y. The regeneratedkernel/config-microvmandconfig-microvm.derivedare generated files, anddoc/build.mdis docs.Old tests of the area
guest::exec::tests::a_stalled_sink_stalls_only_its_own_execution_and_loses_nothing, which failed on GitHub'subuntu-26.04runners until tests: keep the Linux tests true with Ubuntu 26.04's coreutils #1535, leaves withguest::exec.guest::root::tests' 6 bootstrap tests andguest::sys::spawn::tests'a_child_enters_its_root_or_reports_why_not,the_check_s_credentials_keep_the_parent_s_supplementary_groupsandan_entry_leads_a_session_and_keeps_its_barrier_from_the_programtest the deleted bootstrap and child stages.guest::cgroup::tests, 17 testslayouts_keep_the_agent_out_of_the_workload_subtree,executions_run_in_the_workload_cgroup_or_in_one_child_of_it,preparation_creates_the_cgroup_and_enables_its_controllers_together,invalid_resources_change_nothing,an_execution_s_own_cgroup_is_new_and_takes_its_controllers_from_the_workload,a_failed_preparation_leaves_no_cgroup_of_the_execution_s_own,an_empty_resource_value_reaches_its_file_as_a_newline,occupancy_is_the_scope_s_canonical_process_count,a_kill_reaches_the_scope_s_cgroup_alone,settlement_collects_statuses_between_its_checks_until_the_deadline,processes_are_placed_in_the_execution_s_cgroup,a_handle_reaches_its_own_cgroups_alone_once_another_takes_a_path,only_an_empty_cgroup_of_the_execution_s_own_is_removed,cgroup_operations_leave_an_unrelated_child_s_status,descendants_that_hold_pipes_are_found_and_settled,a_removal_leaves_a_cgroup_prepared_at_its_path_by_a_concurrent_one,a_failed_preparation_removes_its_own_cgroup_aloneguest::entry::tests, 22 teststhe_allowlist_holds_the_thirteen_capabilities,capability_sets_add_remove_and_list_their_members,every_capability_outside_the_allowlist_is_refused,only_user_id_zero_may_hold_capabilities,published_listeners_refuse_binding_and_raw_sockets,invalid_roots_ids_groups_and_hostnames_are_refused,existing_accounts_are_read_below_the_root,account_databases_are_bounded_regular_files_reached_through_no_link,an_entry_needs_a_root_directory,runtime_binds_need_a_mount_root_unless_there_are_none,runtime_binds_are_made_in_order_and_removed_in_reverse,a_failed_runtime_bind_removes_the_binds_before_it,a_failed_runtime_bind_names_the_binds_before_it_that_stay,a_runtime_bind_that_stays_is_reported,device_sets_select_their_nodes,each_entry_stage_reports_its_own_failure_and_runs_nothing,a_denied_umask_fails_the_proc_stage_and_runs_nothing,an_entered_program_leads_a_session_without_a_terminal_or_the_callers_descriptors,an_entered_program_ignores_and_blocks_no_signal_of_its_caller_s,an_entry_needs_a_placement_and_neither_a_root_nor_a_check,privileged_entries_see_their_own_view_and_identity,privileged_runtime_binds_are_removed_before_a_teardownguest::exec::tests, 44 testsa_program_s_launch_output_and_status_are_reported,a_failed_launch_stage_is_reported_and_the_execution_still_ends,an_execution_without_output_ends_through_its_descriptors_alone,concurrent_executions_progress_independently,a_stalled_sink_stalls_only_its_own_execution_and_loses_nothing,cancellation_ends_a_stalled_program_and_the_caller_discards_the_rest,stdin_eof_follows_every_byte_that_a_write_took,a_program_that_closes_its_input_ends_the_writes_without_sigpipe,concurrent_writers_meet_closed_inputs_without_sigpipe,a_timeout_ends_the_program,a_timeout_whose_signals_the_kernel_refuses_fires_once,a_disconnection_discards_the_output_and_ends_the_execution,causes_count_only_while_the_program_runs,an_observed_status_ends_the_execution,a_caller_that_reaps_is_the_program_s_only_collector,ending_the_program_ends_the_process_group_that_it_leads,a_status_that_another_collector_took_first_is_left_to_it,a_start_after_another_collector_took_the_status_ends_nothing_by_id,the_program_s_end_closes_its_input_for_a_descendant_that_reads_it,dropping_an_unfinished_execution_ends_its_program,an_unrelated_child_s_status_is_left_alone,both_streams_take_turns_while_each_has_output,the_cgroup_is_killed_once_another_collector_took_the_status_with_the_output_held,the_cgroup_is_killed_once_the_program_ends_with_its_output_held,a_failed_kill_is_reported,a_kill_never_reaches_a_cgroup_that_took_the_path_later,a_failed_start_ends_the_program_and_its_cgroup_even_without_descriptors,a_failed_start_ends_a_program_that_joined_another_process_group,the_program_s_ends_block_and_the_execution_s_do_not,an_adopted_program_s_launch_comes_at_once_then_its_output_and_status,an_adopted_program_reads_its_input_to_its_end,an_adopted_program_that_a_nonblocking_pidfd_names_runs_as_any_other,an_adopted_program_that_its_id_names_is_cancelled_with_its_process_group,an_adopted_program_whose_status_was_observed_has_ended_and_its_output_is_read,adopting_a_program_whose_status_another_collector_took_ends_nothing_by_id,a_failed_adoption_ends_the_program_and_its_cgroup_without_descriptors,adopted_ends_are_pipe_ends_that_go_the_way_of_their_streams,a_program_that_handles_a_signal_ends_with_its_own_status_and_all_of_its_output,a_program_that_ignores_a_signal_runs_until_the_caller_terminates_it,a_signal_reaches_the_process_group_that_the_program_leads_if_the_options_say_so,a_signal_reaches_each_process_once,a_signal_reaches_nothing_once_a_collector_took_the_program_s_status,a_failed_group_lookup_is_an_error_that_sends_no_second_signal,a_kill_and_a_signal_that_the_kernel_refuses_are_errors_that_end_nothingguest::process::tests, 9 testsa_named_child_s_status_is_collected_and_no_other,a_pidfd_polls_readable_once_its_child_ends,a_child_named_by_the_caller_s_pidfd_is_waited_for_through_it,a_child_that_reports_its_end_with_no_signal_is_waited_for,an_observed_status_belongs_to_its_child_alone,stops_and_continuations_do_not_end_an_observed_child,a_traced_child_s_stop_does_not_end_it,a_child_whose_status_another_collector_took_is_echild,ids_that_no_process_can_have_are_refusedguest::root::bootstrap::tests, 2 testskernel_threads_are_known_by_their_flags,membership_lists_are_decimal_linesguest::root::tests, 6 testsbootstrap_moves_every_process_but_kernel_threads_and_applies_the_resources,bootstrap_mounts_the_hierarchy_unless_the_parent_is_a_cgroup,bootstrap_names_the_failed_step_and_keeps_the_earlier_changes,bootstrap_accepts_a_missing_sysctl_only_without_user_namespaces,bootstrap_fails_while_a_process_keeps_returning_to_the_parent,bootstrap_succeeds_when_the_last_pass_empties_the_parentguest::spawn::tests, 22 testsa_program_runs_with_its_arguments_environment_and_streams,a_program_without_an_environment_inherits_its_parent_s,inherited_descriptors_stay_open_at_their_numbers_and_others_close,the_working_directory_and_physical_pwd_follow_the_command,a_program_named_without_a_slash_is_searched_for_in_the_command_s_path,a_search_skips_a_path_longer_than_path_max,a_search_refuses_a_name_longer_than_name_max,a_search_s_memory_is_bounded_whatever_its_name_and_path,launch_stage_failures_are_reported_and_run_nothing,a_child_joins_its_cgroup_and_enters_its_checked_directory,invalid_commands_fail_to_spawn,short_and_unknown_reports_are_protocol_errors,launch_stages_keep_their_numbers,launch_stages_are_in_their_order,a_child_waits_at_its_barrier_until_released,a_dropped_barrier_cancels_the_launch,a_dropped_barrier_cancels_its_launch_while_another_child_waits_at_its_own,another_childs_pipes_hang_up_while_a_child_waits_at_its_barrier,releasing_the_barrier_of_an_ended_child_fails,a_new_session_has_no_controlling_terminal,a_program_keeps_its_caller_s_ignored_and_blocked_signals_unless_its_command_resets_them,a_child_whose_report_has_no_reader_still_exits_with_the_launch_failure_statusguest::sys::spawn::tests, 3 testsa_child_enters_its_root_or_reports_why_not,the_check_s_credentials_keep_the_parent_s_supplementary_groups,an_entry_leads_a_session_and_keeps_its_barrier_from_the_programguest::sys::spawn::tests:invalid_specs_are_refused_before_forking,stream_sources_below_the_standard_streams_are_raised_and_kept_from_the_programandthe_launch_descriptors_are_close_on_execlose their cases of the credentials check, inherited descriptors and the cgroup placement.guest::sys::entry::tests::the_kernel_structures_have_their_uapi_sizeslosesCloneArgsandOpenHow.guest::sys::port::tests::transactions::a_thread_that_may_hold_the_permission_spawns_no_commandspawns throughsys::spawn'sChildSpecandPreparedChildrather thanguest::spawn::Command, with the same refusals and the same empty launch report.guest::sys::signal::tests::a_write_takes_back_its_own_sigpipe_beside_one_pending_for_the_processandguest::init::tests::exec::a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_endingwait withsys::waitrather thanguest::process::Child::waitandwait_named, for the same statuses.guest::init::tests::exec::privileged_capture_sweep_kills_setsid_escapees_and_spares_both_helpersreads process groups withgetpgidrather thanprocess_group_of.guest::sys::process::tests::a_real_time_signal_goes_through_a_pidfd_and_to_a_process_groupdrops its check ofprocess_group_of; its signals to the group still succeed.guest::managed_agent::dispatch::tests::runtime::privileged_layered_runtime_stops_before_attach_on_pending_sigterm, with the helperstermination,prelaunch_terminationandbackpressured_termination, signals throughsys::tests' re-export ofsignal_through_pidfd: only the path changes.scripts/test_nvx_tools.py'sNvxRsTests.test_readme_gives_each_module_a_short_row_and_a_sectionexpects more than 30 rows innvx-rs/README.md's module table rather than 40: the table keeps 39 of its 44 rows. The floor only shows that the test reads the module table, and SL6.13b will leave 36.guest::rootand the kept OS modules.Test changes
python scripts/check_test_changes.py --base origin/feature/nvx-refactorlists 268 changes to existing tests, hencetests-modified:root::kernel::tests' fake writes and process moves (pin,writes,move_process,write),root::tests' bootstrap fixtures (Process,hierarchy,bootstrap_in,interface_files),sys::entry::tests'Simulation,sys::fd::tests'set_descriptor_limit,sys::process::tests'spawn_child_without_exit_signal,spawn_traced_childandcontinue_traced, andsys::spawn::tests'CAP_SYS_CHROOT; and the 10 test hooks of deleted code (ExecutionCgroup::{prepare, remove},Entry::prepare,guest::exec'sleads_its_groupandsignal_through_pidfd,EntryChildwithclone_flagsandstage, andPreparedChild::{take_credentials, restore_credentials}).Operation,CallandStateofroot::kernel::tests, which lose the write; the three runtime helpers above (paths only); and the imports ofroot::testsandsys::tests, whose re-exports follow the deleted helpers.Validation
local_gates.py --files(fromdev) selectstest-changes,markdown-links,test-layout, every step ofcheck-nvx-rsandnvx-cli(validate-nvx), on both systems; its runtime-adapter gates no longer exist on this branch. I ran them from this branch's action definitions, at the heads that the tables give. The branch moved with its stack, withrerereoff each time:321bd2b5, where the only conflict wasguest/exec/tests.rs, which tests: keep the Linux tests true with Ubuntu 26.04's coreutils #1535 changed and this PR deletes;bf2c816e, after SL6.4 (host: make image staging and artifact discovery private to the CLI (SL6.4) #1533) merged, and onto04fbbd48, as which guest: delete the Alpine one-shot container helpers (SL7.8c) #1536 merged with the same tree, without conflicts;22163771(nvx-rs: serve NVXC v2 in the guest loop and the fake OpenVMM (SL4.4b) #1531), without conflicts: SL4.4b's NVXC v2 changes to the guest loop and the managed agent use nothing that this PR deletes, andgit range-diffshows only context changes.The README floor.
test_readme_gives_each_module_a_short_row_and_a_sectionrequired more than 40 rows innvx-rs/README.md's module table. This PR's runs of validate-nvx's unittest list, at004d770eand543248e7, sat on321bd2b5, where the table had 46 rows and this PR left 41. SL6.4 then removed 2 (nvx::host::artifactsandnvx::host::seal), so from the restack ontobf2c816eon the table kept 39, and after that restack I had rerun only the Rust gates and the K1 smoke run, not the Python tests. The deletion commit now lowers the floor to 30 (see Old tests of the area), and the list passes again on the final head.On the final head,
9830b1e1, on22163771:nvx-mshv-testnvx-kvm-testcargo fmt --all --check, andcargo clippy --lockedwith-D warningsfor--all-targets --all-features,--lib,--lib --no-default-features, andserde,cliandtestingalone, and on Linux--all-targets --no-default-features --features guestcargo test --locked --all-featuresmanaged_agent::dispatch::tests::streamstests, which fail at22163771too, as their 19 siblings do ("the isolated test process failed")cargo test --locked,--lib --no-default-features,cargo docwith-D warnings,cargo +1.89 check(MSRV)python3 scripts/public_api.py,cargo check --target aarch64-apple-darwinnvx.py check-guest-binaries(musl lint and tests),build-guest-binaries,test-guest-binariesguest::init::tests::execfailures on kernel 6.6scripts/test_nvx_tools.pytest_adversarial.py,nvx.py's--helpcommands--helpnvx.py verify,check_test_layout.py,check_markdown_links.py, SL5.2'scheck_matrix.py,check_test_changes.pyWindows, this workstation (Rust 1.95.0), on
004d770e(the deletion before the second restack):cargo fmt --all --checkcargo clippy --lockedwith-D warnings:--all-targets --all-features,--lib,--lib --no-default-features, andserde,cliandtestingalonecargo test --locked --all-featurescargo test --lockedcargo build --locked --lib --no-default-features,cargo test --locked --lib --no-default-featuresRUSTDOCFLAGS=-D warnings cargo doc --locked --no-deps --all-featurescargo +1.89 check --locked --all-targets --all-features(MSRV)validate-nvx's unittest list,test_adversarial.pyandnvx.py's--helpcommandstest_adversarial.py84, 11 skippedpython scripts/nvx.py verify,check_test_layout.py,check_markdown_links.pycheck_matrix.py <worktree> 99d2022085fcheck_test_changes.pyLinux,
nvx-mshv-test(Azure Linux 3, kernel 6.18, MSHV, virtual machine) andnvx-kvm-test(Azure Linux 3, kernel 6.6, KVM, virtual machine), each in a worktree of this branch with its own target directory, every signal at its default disposition, on004d770e:cargo fmt, andcargo clippywith-D warningsfor every feature set above and--no-default-features --features guest --all-targetscargo test --locked --all-featuresguest::init::tests::exec, 19 inmanaged_agent::dispatch::tests, 2 inmanaged_agent::tests::loopback), none newcargo test --locked,--lib --no-default-features,cargo docwith-D warningspython3 scripts/public_api.py(both snapshots)cargo +1.89 check(MSRV),cargo check --target aarch64-apple-darwinnvx.py check-guest-binaries(musl lint and tests)guest::init::tests::execfailures on kernel 6.6, none newnvx.py build-guest-binaries,test-guest-binariesThe base,
00341544(SL7.8b's head) measured on the same hosts, failed the same KVM tests plus three that this PR deletes (guest::entry::tests::runtime_binds_need_a_mount_root_unless_there_are_noneand twoguest::exectests); MSHV passed everything there too.microVM scenarios on both backends, with the Alpine, Ubuntu and Azure Linux initramfses built from this branch on
nvx-kvm-test(SHA-25622c52f69…,af1610af…and73ca3879…, identical before and after the restack, and copied tonvx-mshv-testwith their digests checked), and CI run 43185976865's kernel, Ubuntu distro layer, scratch template and OpenVMM (692ac2a9…,86c6685a…,1d0d8c89…and75fb488d…, checked by SHA-256), whose inputs match this branch's:guest-boot,guest-identity,console-exit,lifecycle,managed-lifecycle,workload-identity,console-snapshot,network-snapshot,filesystem-snapshotmanaged-exec-config,sandbox-lifecycle,sandbox-proxy-only,sandbox-ram-upper,sandbox-gpt-layer,vm-lifecycle,untiered-network-policy,snapshot-core,snapshot-tiersrestore-processors, 1 and 2 vCPUs and untargetedguest-boot,guest-identity,console-exit,lifecycle,virtio-net,filesystem-snapshotguest-boot,guest-identity,console-exit,virtio-net,network-snapshot,workload-identity,managed-lifecycleNo OpenVMM process was left. These scenarios ran on CI's kernel, before K1.
K1, on
543248e7(K1 before the second restack, the same tree for the kernel's inputs) unless a row says otherwise:nvx.py kernel-config(in the Docker build's image, onnvx-kvm-test)nvx.py kernel-config --check,nvx.py check-kernel-config,nvx.py verifytest_kernel_config.py,test_kconfig.py(Linux and Windows)docker build --target kernel-artifactsand--target kernel-debug-artifacts, as CI builds them, withbuild-kernel's required-group checks and its inventory check ("kernel configuration matches its inventory (188 settings, 593 derived symbols)", exact toolchain)vmlinux8b133efd…(config60f480bf…) andvmlinux-debug16f57573…, both with# CONFIG_MAGIC_SYSRQ is not setruff check,ruff format --check,compileall,pyrightfor Linux and Windowsvalidate-nvx's unittest listcheck_markdown_links.pyThe K1 kernel, with this branch's Alpine image and CI's distro layer, scratch template and OpenVMM, booted on all three backends:
guest-boot,console-exit,sandbox-lifecycle,snapshot-core(named snapshot restores) andrestore-processors(1 and 2 vCPUs and untargeted) passed on KVM (nvx-kvm-test), MSHV (nvx-mshv-test) and WHP (nvx-whp-test, a Windows WHP virtual machine, with CI's Windows OpenVMM7abd8c8d…), and no OpenVMM process was left.On MSHV, typing
a,^O,h,band Enter intoread -r linein annvx-rs runshell:/proc/sysrq-trigger,kernel.sysrq692ac2a9…1sysrq: HELP : loglevel(0-9) reboot(b) crash(c) …61 62:^Oandhnever reached it8b133efd…61 0f 68 62:^Oandhreached itCI, run 43268333520 on
9830b1e1: both kernels built onubuntu-26.04for the first time (runner image 20261101.186.1), from the Docker build rather than a cache, with "kernel configuration matches its inventory (188 settings, 593 derived symbols)"; itsvmlinux.configis the one built above (60f480bf…,# CONFIG_MAGIC_SYSRQ is not set). Every job passed on the first attempt butnvx-rs / windows-latest, wheretests/cli/exec_lock.rs::exec_processes_contend_but_other_sandboxes_and_stop_proceed'snvx-rs sandbox stop --timeout 0.1failed witherror[still-running]: cannot confirm exit of VM process 7540: a host CLI test with the fake OpenVMM on Windows, whose build this PR doesn't change (it changes only Linux guest code, docs, scripts and the kernel's configuration), and which passed on the base's push run (43263930955), on this workstation at9830b1e1, and on the rerun of the failed jobs, with which the run completed green.